package com.lill.support.aspect;

import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lill.common.component.server.config.ThreadPoolAspectConfig;

@Component
@Aspect
public class ApiParamsAspect {

	protected static Logger logger = LoggerFactory.getLogger(ApiParamsAspect.class);
	//  
	private final ObjectMapper mapper;

	@Autowired
	public ApiParamsAspect(ObjectMapper mapper) {
		this.mapper = mapper;
	}

	/**
	 * 定义请求日志切入点，其切入点表达式有多种匹配方式,这里是指定路径
	 */
	@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
	public void apiParamsPointcut() {
	}
	
	@Around("apiParamsPointcut()")
	public Object doAroundService(ProceedingJoinPoint pjp) throws Throwable {
		long begin = System.nanoTime();
		Object obj=pjp.proceed();
		long end =System.nanoTime();
		printSaveRequestTime(pjp.getArgs(),pjp.getTarget().getClass().getName(),pjp.getSignature().getName(), begin, end);
		return obj;
	}

	private void printSaveRequestTime(Object[] objParams,String className,String methodName, long begin,long end) {
		ThreadPoolAspectConfig.executorAsyncHandle(new Runnable() {
			@Override
			public void run() {
				long logTime=(end-begin)/1000000;
				logger.info("调用Service方法：{}.{}，参数：{}，执行耗时：{}纳秒，耗时：{}毫秒",
						className,methodName,Arrays.toString(objParams),(end-begin),logTime);
				StringBuffer paramBuf=new StringBuffer().append(className)
						.append(".").append(methodName).append(":").append("parameter:");
				for (Object object : objParams) {
					if (object instanceof MultipartFile
							|| object instanceof HttpServletRequest
							|| object instanceof HttpServletResponse 
							|| object instanceof MultipartFile[]) {
						continue;
					}
					try {
						paramBuf.append(mapper.writeValueAsString(object));
					} catch (Exception e) {
						logger.error(e.getMessage(), e);
					}
				}
				logger.info("request parameter:"+paramBuf.toString());
			}
		});
	}

//	@AfterReturning(returning = "response", pointcut = "apiParamsPointcut()")
//	public void doAfterReturning(Object response) {
//		logger.info("----------start response parameter--------------");
//		try {
//			if (response != null) {
//				logger.info("response parameter : "+ mapper.writeValueAsString(response));
//			}
//		} catch (Exception e) {
//			logger.error(e.getMessage(), e);
//		}
//		logger.info("----------end response parameter--------------");
//	}
}
